* Fix off-by-one in nmea reader
Found with afl and address sanitizer:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==
2615627==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f54eaa53683 bp 0x7ffd187eed00 sp 0x7ffd187ee4b8 T0)
==
2615627==The signal is caused by a READ memory access.
==
2615627==Hint: address points to the zero page.
#0 0x7f54eaa53682 in QString::chop(int) (/lib64/libQt5Core.so.5+0x13c682)
#1 0x5e8d7f in gpgsa_parse /home/gpsbabel/gpsbabel.git/nmea.cc:744
#2 0x5e8d7f in nmea_parse_one_line /home/gpsbabel/gpsbabel.git/nmea.cc:1021
#3 0x5f0b6f in nmea_read /home/gpsbabel/gpsbabel.git/nmea.cc:1096
#4 0xc7e483 in run /home/gpsbabel/gpsbabel.git/main.cc:339
#5 0x4ced15 in main /home/gpsbabel/gpsbabel.git/main.cc:707
#6 0x7f54ea3f71a2 in __libc_start_main (/lib64/libc.so.6+0x271a2)
#7 0x4cffdd in _start (/home/gpsbabel/gpsbabel.git/gpsbabel+0x4cffdd)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib64/libQt5Core.so.5+0x13c682) in QString::chop(int)
==
2615627==ABORTING
* Fix heap buffer overflow in igc reader
In gbfgetstr(), when file->buff contains exactly file->buffsz
characters including null termination, there is no room to
append another character with strcat() in igc.cc
Found by afl with address sanitizer:
==
2082077==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x611000001f40 at pc 0x7f5a4e0da6cd bp 0x7ffd14ffe040 sp 0x7ffd14ffd7e8
WRITE of size 2 at 0x611000001f40 thread T0
#0 0x7f5a4e0da6cc (/lib64/libasan.so.5+0x9b6cc)
#1 0x7327cf in data_read /home/gpsbabel/gpsbabel.git/igc.cc:334
#2 0xc7a3c1 in run /home/gpsbabel/gpsbabel.git/main.cc:339
#3 0x4cddf2 in main /home/gpsbabel/gpsbabel.git/main.cc:707
#4 0x7f5a4d5e51a2 in __libc_start_main (/lib64/libc.so.6+0x271a2)
#5 0x4cf00d in _start (/home/gpsbabel/gpsbabel.git/gpsbabel+0x4cf00d)
0x611000001f40 is located 0 bytes to the right of 256-byte region [0x611000001e40,0x611000001f40)
* Fix endless loop in mapsource
The loop around gbfread needs a check for eof, otherwise it
may never terminate with special input created by afl.
} else {
// Store other header data in the track descriptions
if (strlen(trk_desc) < MAXDESCLEN) {
- strcat(ibuf, HDRDELIM);
remain = MAXDESCLEN - strlen(trk_desc);
strncat(trk_desc, ibuf, remain);
+ remain = MAXDESCLEN - strlen(trk_desc);
+ strncat(trk_desc, HDRDELIM, remain);
}
}
break;
data (min 22 bytes) terminated by a zero */
do {
gbfread(tbuf, 1, 1, mps_file);
- } while (tbuf[0]);
+ } while (tbuf[0] && !gbfeof(mps_file));
/* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */
gbfread(tbuf, 18, 1, mps_file);
data (min 22 bytes) terminated by a zero */
do {
gbfread(tbuf, 1, 1, mps_file);
- } while (tbuf[0]);
+ } while (tbuf[0] && !gbfeof(mps_file));
/* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */
gbfread(tbuf, 18, 1, mps_file);
// 0 = "GPGSA"
// 1 = Mode. Ignored
QChar fix;
- if (nfields > 1) {
+ if (nfields > 2) {
fix = fields[2][0];
}
}
float pdop = 0, hdop = 0, vdop = 0;
- if (nfields > 14) pdop = fields[15].toFloat();
- if (nfields > 15) hdop = fields[16].toFloat();
- if (nfields > 16) {
+ if (nfields > 15) pdop = fields[15].toFloat();
+ if (nfields > 16) hdop = fields[16].toFloat();
+ if (nfields > 17) {
// Last one is special. The checksum isn't split out above.
fields[17].chop(3);
vdop = fields[17].toFloat();